/*
 *所有关于sale_partner_monthly_statics类的业务代码应在此处编写
*可使用repository.调用常用方法，获取EF/Dapper等信息
*如果需要事务请使用repository.DbContextBeginTransaction
*也可使用DBServerProvider.手动获取数据库相关信息
*用户信息、权限、角色等使用UserContext.Current操作
*sale_partner_monthly_staticsService对增、删、改查、导入、导出、审核业务代码扩展参照ServiceFunFilter
*/
using ATkg.BizAppProject.DomainModels;
using ATkg.BizAppProject.IRepositories;
using DGZImp.Core.BaseProvider;
using DGZImp.Core.DbSqlSugar;
using DGZImp.Core.Exceptions;
using DGZImp.Core.Extensions;
using DGZImp.Core.Extensions.AutofacManager;
using DGZImp.Core.Utilities;
using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using MySqlX.XDevAPI;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using System;
using System.Linq;
using System.Linq.Expressions;
using System.Net.Http;
using System.Security.Policy;
using System.Text;

namespace ATkg.BizAppProject.Services
{
    public partial class sale_partner_monthly_staticsService
    {
        private readonly IHttpContextAccessor _httpContextAccessor;
        private readonly Isale_partner_monthly_staticsRepository _repository;//访问数据库
        //private readonly AmesSyncService _ames;

        public HttpClient client = null;
        public static IHttpClientFactory _httpClientFactory { get; set; }

        public string url = "";
        public string db = "";
        public string userName = "";
        public string password = "";
        public static int? uid = 0;

        [ActivatorUtilitiesConstructor]
        public sale_partner_monthly_staticsService(
            Isale_partner_monthly_staticsRepository dbRepository,
            IHttpContextAccessor httpContextAccessor,
            IHttpClientFactory httpClientFactory
            //AmesSyncService ames
            )
        : base(dbRepository)
        {
            _httpContextAccessor = httpContextAccessor;
            _repository = dbRepository;
            _httpClientFactory = httpClientFactory;
            //_ames = ames;
            //多租户会用到这init代码，其他情况可以不用
            //base.Init(dbRepository);
        }
        //定义销售月度报表字段
        public class Sale_Partner_Monthly_Statics
        {
            public int id { get; set; }
            public string year { get; set; }
            public decimal contract_amount { get; set; }
            public string factory { get; set; }
            public decimal delivery_amount { get; set; }
            public decimal budget_amount { get; set; }
            public decimal last_contract_amount { get; set; }
            public decimal last_year_delivery_amount { get; set; }

            //public DateTime write_date { get; set; }
        }
        public async Task<JObject> Call(string service, string method, List<dynamic> args)
        {
            client = _httpClientFactory.CreateClient();
            var json = new
            {
                jsonrpc = "2.0",
                method = "call",
                @params = new { service = service, method = method, args = args },
                id = Guid.NewGuid(),
            };
            try
            {
                Console.WriteLine(JsonConvert.SerializeObject(json));
                //Console.WriteLine("准备获取uid1");
                var content = new StringContent(JsonConvert.SerializeObject(json), Encoding.UTF8, "application/json");
                //Console.WriteLine("准备获取uid2");
                Console.WriteLine(content);
                //logger.LogInformation("---开始请求AMES获取数据---");
                //logger.LogInformation(JsonConvert.SerializeObject(json));
                client.Timeout = TimeSpan.FromSeconds(300);
                //Console.WriteLine("准备获取uid3");
                Console.WriteLine(url, content);
                var response = await client.PostAsync(url, content);
                //Console.WriteLine("准备获取uid4");
                response.EnsureSuccessStatusCode();
                //Console.WriteLine("准备获取uid5");
                var responseString = await response.Content.ReadAsStringAsync();
                //Console.WriteLine("准备获取uid6");
                //logger.LogInformation(responseString);
                var responseJson = JObject.Parse(responseString);
                //Console.WriteLine("准备获取uid7");
                return responseJson;
            }
            catch (Exception e)
            {
                throw new AppException(e.Message);
            }
        }
        public async Task<int?> GetOdooUid(string username, string password)
        {
            var res = await Call("common", "login", new List<dynamic> { db, username, password });
            return Convert.ToInt32(res["result"]);
        }


        //空港和爱科read_group
        public async Task<JObject> CallReadGroup(string model, List<object> domain, List<string> groupBy, List<string> fields, object pageData)
        {
            var param = new List<object>();
            param.Add(db);
            // if (uid == null || uid == 0)
            uid = await GetOdooUid(userName, password);
            param.Add(uid);
            param.Add(password);
            param.Add(model);
            param.Add("read_group");
            param.Add(new List<object> { domain, fields, groupBy, });
            param.Add(pageData);
            JObject data = null;
            try
            {
                data = await Call("object", "execute_kw", param);

            }
            catch (Exception ex)
            {
                //_ames.logger.LogError(ex, $"获取aMES数据失败，请求内容：{JsonConvert.SerializeObject(param)}，错误信息：{ex.Message}");
                throw new AppException(ex.ToString());
            }

            return data;
        }
        //北方read_group方法
        public async Task<JObject> CallWebReadGroup(string model, List<object> domain, List<string> groupBy, List<string> fields, object pageData)
        {
            //Console.WriteLine("AAAAAAAAA");
            var param = new List<object>();
            param.Add(db);
            //if (uid == null || uid == 0)              //userName, password全局变量
            uid = await GetOdooUid(userName, password);
            //Console.WriteLine(uid);


            // 验证输出
            //Console.WriteLine("Domain structure type: " + result["domain"].GetType().Name);
            //Console.WriteLine("Specification keys: " + string.Join(", ", specification.Keys));

            param.Add(uid);
            param.Add(password);
            param.Add(model);
            param.Add("read_group");
            // 动态获取 pageData 的属性值
            int limit = (int?)pageData.GetType().GetProperty("limit")?.GetValue(pageData) ?? 10000;
            int offset = (int?)pageData.GetType().GetProperty("offset")?.GetValue(pageData) ?? 0;
            dynamic context = pageData.GetType().GetProperty("context")?.GetValue(pageData);
            //param.Add(new List<object> { domain, fields, groupBy, });
            //param.Add(new List<object> { });
            //param.Add(result);
            var methodParams = new List<object>
            {
                domain,          // domain
                fields,          // fields
                groupBy,         // groupby
                offset,          // offset
                limit,           // limit
                null,            // orderby
                true             // lazy
            };
            param.Add(methodParams);
            // 如果需要上下文，可以添加
            if (context != null)
            {
                param.Add(new Dictionary<string, object> { { "context", context } });
            }

            JObject data = null;
            try
            {
                data = await Call("object", "execute_kw", param);
               // _ames.logger.LogInformation($"成功调用 read_group: {model}");
            }
            catch (Exception ex)
            {
               // _ames.logger.LogError(ex, $"获取aMES数据失败，请求内容：{JsonConvert.SerializeObject(param)}，错误信息：{ex.Message}");
                throw new AppException($"调用 read_group 失败: {ex.Message}");
            }
            //Console.WriteLine(data);
            //Console.WriteLine("EFS0534");
            return data;
        }
        //同步空港销售数据
        public async Task<List<Sale_Partner_Monthly_Statics>> SyncSalePartnerMonthlyStatics_KongGang()
        {
            userName = "haoxiaona@atmcn.com";
            password = "Hao123456";
            //url = "http://10.7.1.9/jsonrpc";
            //db = "prd0803";
            url = "http://10.7.1.3/jsonrpc";
            db = "atm";

            var qDomain = new List<object>
            {
                
                //new List<object> {"write_date",">=", DateTime.Today},
                new List<object> {"user_id.active", "=", true  },
                new List<object> { "partner_id.name", "not in", new List<string> { "B0R","BBW" } },
            };
            var qGroupBy = new List<string>
            {

                "year",
                //"partner_id",
            };
            var qFields = new List<string>
            {
               
                //"partner_id",
                "year",
                "contract_amount",
                "delivery_amount",
                "budget_amount",
                "last_contract_amount",
                "last_year_delivery_amount",

            };
            var qPage = new
            {
                context = new { lang = "zh_CN", tz = "Asia/Shanghai" },
                limit = 10000,
                offset = 0,
                lazy = true
            };
            var resp = await CallReadGroup("atm.sale.partner.monthly.statics", qDomain, qGroupBy, qFields, qPage);
            if (resp.ContainsKey("error"))
            {
                var message = $"【拉取单据】{resp["error"].ToString()}";
                throw new AppException(message);
            }
            //return resp;        //直接输出接口返回的值用于调试
            var res = (JArray)resp["result"];

            if (res == null || res.Count <= 0)
            {
                return null;
            }
            var r = new List<Sale_Partner_Monthly_Statics>();
            foreach (var item in res)
            {
                var x = (JObject)item;

                r.Add(new Sale_Partner_Monthly_Statics
                {
                    //partner_name = x["partner_id"] is JArray ? JArray.FromObject(x["partner_id"])[1].ToString() : "",
                    year = x["year"].ToString(),
                    contract_amount = Convert.ToDecimal(x["contract_amount"]),
                    delivery_amount = Convert.ToDecimal(x["delivery_amount"]),
                    budget_amount = Convert.ToDecimal(x["budget_amount"]),
                    last_contract_amount = Convert.ToDecimal(x["last_contract_amount"]),
                    last_year_delivery_amount = Convert.ToDecimal(x["last_year_delivery_amount"]),
                    factory = "空港",
                    //write_date = DateTime.Parse(x["write_date"].ToString()),
                });
            }
            return r;
        }
        //同步爱科销售数据
        public async Task<List<Sale_Partner_Monthly_Statics>> SyncSalePartnerMonthlyStatics_AiKe()
        {
            userName = "haoxiaona@atmcn.com";
            password = "Hao123456";
            //url = "http://10.7.1.9:81/jsonrpc";
            //db = "sd0605";
            url = "http://10.7.1.4/jsonrpc";
            db = "sd";

            var qDomain = new List<object>
            {
                
                //new List<object> {"write_date",">=", DateTime.Today},
                 new List<object> {"user_id.active", "=", true  },
                 new List<object> { "partner_id.name", "not in", new List<string> { "AT160", "DHM566", "HNN404", "ABF466" } },

            };
            var qGroupBy = new List<string>
            {

                "year",
            };
            var qFields = new List<string> {
                "year",
                "contract_amount",
                "delivery_amount",
                "budget_amount",
                "last_contract_amount",
                "last_year_delivery_amount",
            };
            var qPage = new
            {
                context = new { lang = "zh_CN", tz = "Asia/Shanghai" },
                limit = 10000,
                offset = 0
            };

            var resp = await CallReadGroup("atm.sale.partner.monthly.statics", qDomain, qGroupBy, qFields, qPage);

            if (resp.ContainsKey("error"))
            {
                Console.WriteLine("EEEEEE");
                var message = $"【拉取单据】{resp["error"].ToString()}";
                throw new AppException(message);
            }

            var res = (JArray)resp["result"];

            if (res == null || res.Count <= 0)
            {
                return null;
            }
            var r = new List<Sale_Partner_Monthly_Statics>();
            foreach (var item in res)
            {
                var x = (JObject)item;

                r.Add(new Sale_Partner_Monthly_Statics
                {

                    //partner_name = x["partner_id"] is JArray ? JArray.FromObject(x["partner_id"])[1].ToString() : "", 
                    year = x["year"].ToString(),
                    contract_amount = Convert.ToDecimal(x["contract_amount"]),
                    delivery_amount = Convert.ToDecimal(x["delivery_amount"]),
                    budget_amount = Convert.ToDecimal(x["budget_amount"]),
                    last_contract_amount = Convert.ToDecimal(x["last_contract_amount"]),
                    last_year_delivery_amount = Convert.ToDecimal(x["last_year_delivery_amount"]),
                    factory = "爱科",
                    //write_date = DateTime.Parse(x["write_date"].ToString()),
                });
            }
            return r;
        }

        //同步北方销售数据
        public async Task<List<Sale_Partner_Monthly_Statics>> SyncSalePartnerMonthlyStatics_BeiFang()
        {
            userName = "haoxiaona@atmcn.com";
            password = "Hao123456!";
            //url = "http://10.16.12.81/jsonrpc";
            url = "http://10.16.12.80/jsonrpc";
            db = "bt";

            var qPage = new
            {
                context = new { lang = "zh_CN", tz = "Asia/Shanghai" },
                limit = 10000,
                offset = 0,
            };
            var qDomain = new List<object>
            {
                //"&", "&",
                //new List<object> {"write_date",">=", DateTime.Today},
                 new List<object> {"user_id.active", "=", true  },
                 new List<object> { "partner_id.name", "not in", new List<string> { "AKG002", "AKG001" } },
            };
            var qGroupBy = new List<string>
            {
                "year",
            };
            var qFields = new List<string> {
                "year",
                "contract_amount",
                "delivery_amount",
                "budget_amount",
                "last_contract_amount",
                "last_year_delivery_amount",

            };

            var resp = await CallWebReadGroup("atm.sale.partner.monthly.statics", qDomain, qGroupBy, qFields, qPage);
            if (resp.ContainsKey("error"))
            {
                var message = $"【拉取单据】{resp["error"].ToString()}";
                throw new AppException(message);
            }

            var res = (JArray)resp["result"];
            //return res;

            if (res == null || res.Count <= 0)
            {
                return null;
            }
            var r = new List<Sale_Partner_Monthly_Statics>();
            foreach (var item in res)
            {
                var x = (JObject)item;

                r.Add(new Sale_Partner_Monthly_Statics
                {

                    //partner_name = x["partner_id"] is JArray ? JArray.FromObject(x["partner_id"])[1].ToString() : "",
                    year = x["year"].ToString(),
                    contract_amount = Convert.ToDecimal(x["contract_amount"]),
                    delivery_amount = Convert.ToDecimal(x["delivery_amount"]),
                    budget_amount = Convert.ToDecimal(x["budget_amount"]),
                    last_contract_amount = Convert.ToDecimal(x["last_contract_amount"]),
                    last_year_delivery_amount = Convert.ToDecimal(x["last_year_delivery_amount"]),
                    factory = "北方",
                    //write_date = DateTime.Parse(x["write_date"].ToString()),
                });
            }

            return r;
        }
        //集中三地数据
        public async Task SyncSalePartnerMonthlyStaticsDeal(List<Sale_Partner_Monthly_Statics> r1, List<Sale_Partner_Monthly_Statics> r2 = null, List<Sale_Partner_Monthly_Statics> r3 = null)
        {
            var lists = new[] { r1, r2, r3 }.Where(list => list != null);
            var r = new List<Sale_Partner_Monthly_Statics>();
            foreach (var list in lists)
            {
                var validItems = list.Where(x => x != null).Select(x => new Sale_Partner_Monthly_Statics
                {

                    year = x?.year,
                    contract_amount = Convert.ToDecimal(x.contract_amount),
                    delivery_amount = Convert.ToDecimal(x.delivery_amount),
                    budget_amount = Convert.ToDecimal(x.budget_amount),
                    last_contract_amount = (int)x.last_contract_amount,
                    last_year_delivery_amount = Convert.ToDecimal(x.last_year_delivery_amount),
                    factory = x?.factory,
                    //write_date = (DateTime)x?.write_date,
                });

                r.AddRange(validItems);
            }
            r = r.OrderBy(x => x.year)          //OrderByDescending
                 .ThenBy(x => x.factory)
                 .ToList();
            /*
            if (r.Count > 0)
            {
                Console.WriteLine($"开始插入数据，数量：{r.Count}");
                Console.WriteLine($"r的数据内容：{System.Text.Json.JsonSerializer.Serialize(r, new JsonSerializerOptions { WriteIndented = true })}");
                // 插入数据
                var result = await Db.Storageable(r)
                .WhereColumns(x => new { x.factory,x.year }) // 指定判断重复的列
                .SplitInsert(it => !it.Any()) // 不存在时插入
                .SplitIgnore(it => it.Any())  // 存在时忽略
                .ExecuteCommandAsync();
                Console.WriteLine($"受影响的行数： {result} "); 
            }
            */
            await Db.DoDeleteAsync<Sale_Partner_Monthly_Statics>(x => x.id >= 0, true);
            await Db.DoInsertAsync<Sale_Partner_Monthly_Statics>(r);
        }
    }

}
